home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / cit.arc / LOG.C < prev    next >
C/C++ Source or Header  |  1986-01-10  |  16KB  |  489 lines

  1. /************************************************************************/
  2. /*                log.c                    */
  3. /*                                    */
  4. /*       userlog code for  Citadel bulletin board system        */
  5. /************************************************************************/
  6.  
  7. /************************************************************************/
  8. /*                history                 */
  9. /*                                    */
  10. /* 85Nov15 HAW    MS-DOS library implemented.                */
  11. /* 85Aug31 HAW    Fix <.ep> problem.                    */
  12. /* 85Aug17 HAW    Update to onLine().                    */
  13. /* 85Aug10 HAW    Fix so system doesn't go out to disk on short pwds.    */
  14. /* 85Jul26 HAW    Kill noteLog(), insert anti-hack code in newPW().    */
  15. /* 85Jun13 HAW    Tweak code for networking stuff.            */
  16. /* 85Mar13 HAW    Moved zapLogFile() and logInit and logSort into confg.c.*/
  17. /* 85Jan19 HAW    Fix terminate() so room prompt isn't tossed at modem.    */
  18. /* 85Jan19 HAW    New Users are now directed to type ".help POLICY".    */
  19. /* 85Jan19 HAW    Move findPerson() into file.                */
  20. /* 84Dec15 HAW    Fix bug that allowed discovery of private rooms.    */
  21. /* 84Aug30 HAW    Now we roll into the 16-bit world.            */
  22. /* 84Jun23 HAW&JLS  Eliminating unused local variables using CRF.    */
  23. /* 84Jun19 JLS    Fixed terminate so that Mail> doesn't screw up SYSOP.    */
  24. /* 84Apr04 HAW    Started upgrade to BDS C 1.50a.             */
  25. /* 83Feb27 CrT    Fixed login-in-Mail> bug.                */
  26. /* 83Feb26 CrT    Limited # new messages for new users.            */
  27. /* 83Feb18 CrT    Null pw problem fixed.                    */
  28. /* 82Dec06 CrT    2.00 release.                        */
  29. /* 82Nov03 CrT    Began local history file & general V1.2 cleanup     */
  30. /************************************************************************/
  31.  
  32. #include "ctdl.h"
  33.  
  34. /************************************************************************/
  35. /*                contents                */
  36. /*                                    */
  37. /*    findPerson()        load log record for named person    */
  38. /*    hash()            hashes a string to an integer        */
  39. /*    login()         is menu-level routine to log caller in    */
  40. /*    newPW()         is menu-level routine to change a PW    */
  41. /*    newUser()        menu-level routine to log a new caller    */
  42. /*    PWSlot()        returns CTDLLOG.buf slot password is in */
  43. /*    slideLTab()        support routine for sorting logTab    */
  44. /*    storeLog()        store data in log            */
  45. /*    strCmpU()        strcmp(), but ignoring case distinctions*/
  46. /*    terminate()        menu-level routine to exit system    */
  47. /************************************************************************/
  48.  
  49. /************************************************************************/
  50. /*          External variable declarations in LOG.C        */
  51. /************************************************************************/
  52. int         thisSlot;        /* logTab slot logBuf found via */
  53. char         loggedIn = FALSE;    /* Global have-caller flag    */
  54. char         prevChar;        /* for EOLN/EOParagraph stuff    */
  55. char         expert;        /* true to suppress hints etc.    */
  56. char         termUpper;        /* uppercase only flag        */
  57. char         termLF;        /* LF-after-CR flag        */
  58. char         aide;            /* aide privileges flag     */
  59. char         sendTime;        /* send time msg created    */
  60. char         oldToo;        /* Send last old on new request?*/
  61. unsigned char     termWidth;        /* width to format output to    */
  62. unsigned char     termNulls;        /* # nulls to send at EOLN    */
  63. static char     pwChangeCount;     /* Anti-hack variable        */
  64.  
  65. /************************************************************************/
  66. /*          External variable definitions for LOG.C        */
  67. /************************************************************************/
  68. extern struct logBuffer logBuf;     /* Log buffer of a person    */
  69. extern struct lTable *logTab;        /* RAM index of pippuls     */
  70. extern struct config cfg;        /* Configuration variables    */
  71. extern struct rTable roomTab[];     /* RAM index of rooms        */
  72. extern struct aRoom  roomBuf;        /* Room buffer            */
  73. extern FILE         *logfl;        /* log file descriptor        */
  74. extern int         thisLog;        /* entry currently in logBuf    */
  75. extern char         outFlag;        /* Output skip flag        */
  76. extern char         whichIO;        /* Where IO's going...        */
  77. extern char         haveCarrier;    /* Do we still got carrier?    */
  78. extern char         echo;        /* Who gets what        */
  79. extern char         onConsole;     /* Where we get stuff from    */
  80. extern int         thisRoom;        /* The room we're in        */
  81. extern int         exitValue;
  82.  
  83. /************************************************************************/
  84. /*          External function definitions for LOG.C        */
  85. /************************************************************************/
  86. int  fread();
  87. char toUpper();
  88.  
  89. /************************************************************************/
  90. /*    findPerson() loads log record for named person.         */
  91. /*    RETURNS: ERROR if not found, else log record #            */
  92. /************************************************************************/
  93. int findPerson(name, lBuf)
  94. char            *name;
  95. struct logBuffer    *lBuf;
  96. {
  97.     int  h, i, foundIt, logNo;
  98.  
  99.     h    = hash(name);
  100.     for (foundIt = i = 0;  i < cfg.MAXLOGTAB && !foundIt;  i++) {
  101.     if (logTab[i].ltnmhash == h) {
  102.         getLog(lBuf, logNo = logTab[i].ltlogSlot);
  103.         if (strCmpU(name, lBuf->lbname) == SAMESTRING) {
  104.         foundIt = TRUE;
  105.         }
  106.     }
  107.     }
  108.     if (!foundIt)    return ERROR;
  109.     else         return logNo;
  110. }
  111.  
  112. /************************************************************************/
  113. /*    hash() hashes a string to an integer                */
  114. /************************************************************************/
  115. int hash(str)
  116. char *str;
  117. {
  118.     int  h, i, shift;
  119.  
  120.     for (h=shift=0;  *str;  shift=(shift+1)&7, str++) {
  121.     h ^= (i=toUpper(*str)) << shift;
  122.     }
  123.     return h;
  124. }
  125.  
  126. /************************************************************************/
  127. /*    login() is the menu-level routine to log someone in        */
  128. /************************************************************************/
  129. login(password)
  130. char *password;    /* TRUE if parameters follow    */
  131. {
  132.     char getYesNo();
  133.     int  foundIt, ltentry;
  134.  
  135.     foundIt =     ((ltentry = PWSlot(password, /*load = */TRUE)) != ERROR);
  136.     pwChangeCount = 1;
  137.  
  138.     if (foundIt && *password) {
  139.  
  140.     /* update userlog entries: */
  141.  
  142.     loggedIn     = TRUE;
  143.     setUp(TRUE);
  144.  
  145.     /* recite caller's name, etc:     */
  146.     mPrintf(" %s\n", logBuf.lbname);
  147.  
  148.     logMessage(L_IN, logBuf.lbname);
  149.  
  150.     showMessages(NEWoNLY, FALSE);
  151.  
  152.     listRooms(/* doDull== */ !expert);
  153.  
  154.     outFlag = OUTOK;
  155.     if (
  156.         (
  157.         logBuf.lbId[MAILSLOTS-1]
  158.         -
  159.         (logBuf.lbvisit[   logBuf.lbgen[MAILROOM] & CALLMASK   ]+1)
  160.         < 0x8000
  161.         )
  162.         &&
  163.         logBuf.lbId[MAILSLOTS-1] - cfg.oldest        < 0x8000
  164.         &&
  165.         thisRoom != MAILROOM
  166.     )   {
  167.         mPrintf("\n  * You have private mail in Mail> *\n ");
  168.     }
  169.  
  170.     } else {
  171.     /* discourage password-guessing: */
  172.     if (strLen(password) > 1 && whichIO == MODEM)
  173.         pause(2000);
  174.     if (!cfg.unlogLoginOk  &&  whichIO == MODEM)  {
  175.         mPrintf(" No record -- leave message to 'sysop' in Mail>\n ");
  176.     } else if (getYesNo(" No record: Enter as new user"))    newUser();
  177.     }
  178. }
  179.  
  180. /************************************************************************/
  181. /*    newPW() is menu-level routine to change one's password        */
  182. /*    since some Citadel nodes run in public locations, we avoid    */
  183. /*    displaying passwords on the console.                */
  184. /************************************************************************/
  185. newPW()
  186. {
  187.     char oldPw[NAMESIZE];
  188.     char pw[NAMESIZE];
  189.     int  goodPW;
  190.  
  191.     /* save password so we can find current user again: */
  192.     if (!loggedIn) {
  193.     mPrintf("\n How?\n ");
  194.     return ;
  195.     }
  196.     strcpy(oldPw, logBuf.lbpw);
  197.     storeLog();
  198.     do {
  199.     echo    = CALLER;
  200.     getNormStr(" new password", pw, NAMESIZE, NO_ECHO);
  201.     echo    = BOTH;
  202.  
  203.     /* check that PW isn't already claimed: */
  204.     goodPW = (PWSlot(pw,/* load = */TRUE) == ERROR    &&  strLen(pw) >= 2);
  205.  
  206.     if (pwChangeCount == 0) {
  207.         mPrintf("Hang on....\n");
  208.         pause(3000);            /* Discourage hacking    */
  209.     }
  210.     else pwChangeCount--;
  211.  
  212.     if (!goodPW) mPrintf("\n Poor password\n ");
  213.  
  214.     } while (!goodPW && (haveCarrier || whichIO==CONSOLE));
  215.  
  216.     doCR();
  217.     PWSlot(oldPw, /*load = */TRUE);    /* reload old log entry         */
  218.     pw[NAMESIZE-1] = 0x00;        /* insure against loss of carrier:*/
  219.  
  220.     if (goodPW    &&  strLen(pw) > 1) {    /* accept new PW:        */
  221.     strcpy(logBuf.lbpw, pw);
  222.     logTab[0].ltpwhash    = hash(pw);
  223.     storeLog();
  224.     }
  225.  
  226.     mPrintf("\n %s\n pw: ", logBuf.lbname);
  227.     echo = CALLER;
  228.     mPrintf("%s\n ", logBuf.lbpw);
  229.     echo = BOTH;
  230. }
  231.  
  232. /************************************************************************/
  233. /*    newUser() prompts for name and password             */
  234. /************************************************************************/
  235. newUser()
  236. {
  237.     char    getYesNo();
  238.     char    fullnm[NAMESIZE];
  239.     char    pw[NAMESIZE];
  240.     int     good, g, h, i, ok, ourSlot;
  241.     ulong    low;
  242.  
  243.     configure(FALSE);    /* make sure new users configure reasonably    */
  244.  
  245.     if (!expert)   tutorial("password.blb");
  246.  
  247.     do {
  248.     /* get name and check for uniqueness... */
  249.     do {
  250.         getNormStr(" Name", fullnm, NAMESIZE, ECHO);
  251.         h     = hash(fullnm);
  252.         for (i = 0, good = TRUE; i < cfg.MAXLOGTAB && good; i++) {
  253.         if (h == logTab[i].ltnmhash) good = FALSE;
  254.         }
  255.         if (
  256.         h == 0        /* "HUH?" --HAW 84Aug31         */
  257.         ||
  258.         h == hash("Citadel")
  259.         ||
  260.         h == hash("Sysop")
  261.         ) {
  262.         good = FALSE;
  263.         }
  264.         /* lie sometimes -- hash collision !=> name collision */
  265.         if (!good) mPrintf("We already have a %s\n", fullnm);
  266.     } while (!good    &&  (haveCarrier || whichIO==CONSOLE));
  267.  
  268.     /* get password and check for uniqueness...    */
  269.     do {
  270.         echo    = CALLER;
  271.         getNormStr(" password",  pw, NAMESIZE, ECHO);
  272.         echo    = BOTH    ;
  273.  
  274.         h     = hash(pw);
  275.         for (i = 0, good = strLen(pw) > 1;
  276.          i < cfg.MAXLOGTAB && good;
  277.          i++) {
  278.         if (h == logTab[i].ltpwhash) good = FALSE;
  279.         }
  280.         if (h == 0)   good = FALSE;
  281.         if (!good) {
  282.         mPrintf("\n Poor password\n ");
  283.         }
  284.     } while( !good    &&  (haveCarrier || whichIO==CONSOLE));
  285.  
  286.     mPrintf("\n nm: %s", fullnm);
  287.     mPrintf("\n pw: ");
  288.     echo = CALLER;
  289.     mPrintf("%s\n ", pw);
  290.     echo = BOTH;
  291.     } while (!getYesNo("OK") && (haveCarrier || whichIO==CONSOLE));
  292.  
  293.  
  294.     if (ok && (haveCarrier || whichIO == CONSOLE)) {
  295.  
  296.     logMessage(L_IN, fullnm);
  297.  
  298.     /* kick least recent caller out of userlog and claim entry:    */
  299.     ourSlot         = logTab[cfg.MAXLOGTAB-1].ltlogSlot;
  300.  
  301.  
  302.     slideLTab(0, cfg.MAXLOGTAB-1);
  303.     logTab[0].ltlogSlot = ourSlot;
  304.     getLog(&logBuf, ourSlot);
  305.  
  306.     /* copy info into record:    */
  307.     strcpy(logBuf.lbname, fullnm);
  308.     strcpy(logBuf.lbpw, pw);
  309.     logBuf.lbflags.L_INUSE     = TRUE;
  310.     logBuf.lbflags.NET_PRIVS = FALSE;
  311.     logBuf.credit         = 0;        /* No L-D credit    */
  312.  
  313.     low = cfg.newest-50;
  314.     if (cfg.oldest - low < 0x8000)     low = cfg.oldest;
  315.     for (i=1;  i<MAXVISIT;    i++)   logBuf.lbvisit[i]= low;
  316.     logBuf.lbvisit[                   0]= cfg.newest;
  317.     logBuf.lbvisit[            (MAXVISIT-1)]= cfg.oldest;
  318.  
  319.     /* initialize rest of record:    */
  320.     for (i = 0;  i < MAXROOMS;  i++) {
  321.         if (roomTab[i].rtflags.PUBLIC == 1) {
  322.         g = (roomTab[i].rtgen);
  323.         logBuf.lbgen[i] = (g << GENSHIFT) + (MAXVISIT-1);
  324.         } else {
  325.         /* set to one less */
  326.         g = (roomTab[i].rtgen + (MAXGEN-1)) % MAXGEN;
  327.         logBuf.lbgen[i] = (g << GENSHIFT) + (MAXVISIT-1);
  328.         }
  329.     }
  330.     for (i = 0;  i < MAILSLOTS;  i++)  {
  331.         logBuf.lbslot[i]    = 0l;
  332.         logBuf.lbId[  i]    = cfg.oldest -1;
  333.     }
  334.  
  335.     /* fill in logTab entries    */
  336.     logTab[0].ltpwhash    = hash(pw)       ;
  337.     logTab[0].ltnmhash    = hash(fullnm)       ;
  338.     logTab[0].ltlogSlot    = thisLog       ;
  339.     logTab[0].ltnewest    = logBuf.lbvisit[0];
  340.  
  341.     /* special kludge for Mail> room, to signal no new mail:   */
  342.     roomTab[MAILROOM].rtlastMessage = logBuf.lbId[MAILSLOTS-1];
  343.  
  344.     loggedIn = TRUE;
  345.  
  346.     storeLog();
  347.  
  348.     listRooms(/* doDull== */ !expert);
  349.     mPrintf("\n \n Please type \".Help POLICY\"\n ");
  350.     }
  351. }
  352.  
  353. /************************************************************************/
  354. /*    PWSlot() returns userlog.buf slot password is in, else ERROR    */
  355. /*    NB: we also leave the record for the user in logBuf.        */
  356. /************************************************************************/
  357. int PWSlot(pw, load)
  358. char pw[NAMESIZE], load;
  359. {
  360.     int  h, i;
  361.     int  foundIt, ourSlot;
  362.     struct logBuffer lBuf;
  363.  
  364.     if (strLen(pw) < 2)     /* Don't search for these pwds        */
  365.     return ERROR;
  366.  
  367.     h = hash(pw);
  368.  
  369.     /* Check all passwords in memory: */
  370.     for(i = 0, foundIt = FALSE;  !foundIt && i < cfg.MAXLOGTAB;  i++) {
  371.     /* check for password match here */
  372.  
  373.     /* If password matches, check full password            */
  374.     /* with current newUser code, password hash collisions should    */
  375.     /* not be possible... but this is upward compatable & cheap    */
  376.     if (logTab[i].ltpwhash == h) {
  377.         ourSlot    = logTab[i].ltlogSlot;
  378.         getLog(&lBuf, ourSlot);
  379.  
  380.         if (strCmpU(pw, lBuf.lbpw) == SAMESTRING) {
  381.         /* found a complete match */
  382.         thisSlot = i   ;
  383.         foundIt  = TRUE;
  384.         }
  385.     }
  386.     }
  387.     if (foundIt) {
  388.     if (load == TRUE) {
  389.         movmem(&lBuf, &logBuf, sizeof logBuf);
  390.         thisLog = ourSlot;
  391.     }
  392.     return thisSlot;
  393.     }
  394.     else       return ERROR   ;
  395. }
  396.  
  397. /************************************************************************/
  398. /*    slideLTab() slides bottom N lots in logTab down.  For sorting.    */
  399. /************************************************************************/
  400. slideLTab(slot, last)
  401. int slot;
  402. int last;
  403. {
  404.     int i;
  405.  
  406.     /* open slot up: (movmem isn't guaranteed on overlaps) */
  407.     for (i = last - 1;    i >= slot;  i--)  {
  408.     movmem(&logTab[i], &logTab[i + 1], cfg.sizeLTentry);
  409.     }
  410. }
  411.  
  412. /************************************************************************/
  413. /*    storeLog() stores the current log record.            */
  414. /************************************************************************/
  415. storeLog()
  416. {
  417.     logTab[0].ltnewest      = cfg.newest;
  418.  
  419.     logBuf.lbvisit[0]      = cfg.newest;
  420.     logBuf.lbwidth      = termWidth;
  421.     logBuf.lbnulls      = termNulls;
  422.     logBuf.lbflags.EXPERT = (expert)    ? TRUE : FALSE;
  423.     logBuf.lbflags.UCMASK = (termUpper) ? TRUE : FALSE;
  424.     logBuf.lbflags.LFMASK = (termLF)    ? TRUE : FALSE;
  425.     logBuf.lbflags.AIDE   = (aide)    ? TRUE : FALSE;
  426.     logBuf.lbflags.TIME   = (sendTime)    ? TRUE : FALSE;
  427.  
  428.     putLog(&logBuf, thisLog);
  429. }
  430.  
  431. /************************************************************************/
  432. /*    strCmpU() is strcmp(), but ignoring case distinctions        */
  433. /************************************************************************/
  434. int strCmpU(s, t)
  435. char s[], t[];
  436. {
  437.     int  i;
  438.  
  439.     i = 0;
  440.  
  441.     while (toUpper(s[i]) == toUpper(t[i])) {
  442.     if (s[i++] == '\0')  return 0;
  443.     }
  444.     return  toUpper(s[i]) - toUpper(t[i]);
  445. }
  446.  
  447. /************************************************************************/
  448. /*    terminate() is menu-level routine to exit system        */
  449. /************************************************************************/
  450. terminate(discon)
  451. char discon;
  452.     /* 1.  parameter <discon> is TRUE or FALSE.        */
  453.     /* 2.  if <discon> is TRUE, breaks modem connection    */
  454.     /*     or switches whichIO from CONSOLE to MODEM,    */
  455.     /*     as appropriate.                    */
  456.     /* 3.  modifies externs: struct logBuf,         */
  457.     /*             struct *logTab         */
  458.     /* 4.  returns no values                */
  459.     /*          modified    dvm 9-82            */
  460. {
  461.     int i;
  462.  
  463.     if (loggedIn) {
  464.     mPrintf(" %s logged out\n ", logBuf.lbname);
  465.  
  466.     logBuf.lbgen[thisRoom]    = roomBuf.rbgen << GENSHIFT;
  467.     if (onLine())    storeLog();
  468.     logMessage(L_OUT, "");
  469.     loggedIn = FALSE;
  470.  
  471.     setUp(TRUE);
  472.     }
  473.  
  474.     if (discon)  {
  475.     switch (whichIO) {
  476.     case MODEM:
  477.         interpret(cfg.pHangUp);
  478.         modIn();            /* And now detect carrier loss    */
  479.         break;
  480.     case CONSOLE:
  481.         whichIO =  MODEM;
  482.         printf("\n'MODEM' mode.\n ");
  483.         break;
  484.     }
  485.     }
  486.     for (i = 0; i < MAXROOMS; i++)    /* Clear skip bits */
  487.     roomTab[i].rtflags.SKIP = 0;
  488. }
  489.